#pragma once

#include "Artifact.h"

#include "Manifestation.h"
#include "Operation.h"
#include "Property.h"

namespace uml {

const QString Artifact::fileName_default_ = "";
Artifact::Artifact(const QString& umlType)
    : Classifier(umlType) {}

void Artifact::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    Classifier::fromJson(json, errorList);
    DeployedArtifact::fromJson(json, errorList);
    fileName_ = json.value("fileName").toString(fileName_default_);
    JsonSerializable::fromJsonArray(manifestations_, "manifestations", json, errorList);
    JsonSerializable::fromJsonArray(nestedArtifacts_, "nestedArtifacts", json, errorList);
    JsonSerializable::fromJsonArray(ownedAttributes_, "ownedAttributes", json, errorList);
    JsonSerializable::fromJsonArray(ownedOperations_, "ownedOperations", json, errorList);
}

void Artifact::toJson(QJsonObject& json) {
    Classifier::toJson(json);
    DeployedArtifact::toJson(json);
    if (fileName_ != fileName_default_) {
        json.insert("fileName", fileName_);
    }
    JsonSerializable::toJsonArray(manifestations_, "manifestations", json);
    JsonSerializable::toJsonArray(nestedArtifacts_, "nestedArtifacts", json);
    JsonSerializable::toJsonArray(ownedAttributes_, "ownedAttributes", json);
    JsonSerializable::toJsonArray(ownedOperations_, "ownedOperations", json);
}

/// <summary>
/// fileName getter
/// A concrete name that is used to refer to the Artifact in a physical context.
/// Example: file system name, universal resource locator.
/// </summary>
QString Artifact::fileName() const {
    return fileName_;
}

/// <summary>
/// fileName setter
/// A concrete name that is used to refer to the Artifact in a physical context.
/// Example: file system name, universal resource locator.
/// </summary>
void Artifact::setFileName(const QString& value) {
    fileName_ = value;
}

/// <summary>
/// manifestations getter
/// The set of model elements that are manifested in the Artifact. That is, these
/// model elements are utilized in the construction (or generation) of the artifact.
/// </summary>
vector<shared_ptr<Manifestation>>& Artifact::manifestations() {
    return manifestations_;
}

/// <summary>
/// nestedArtifacts getter
/// The Artifacts that are defined (nested) within the Artifact. The association is
/// a specialization of the ownedMember association from Namespace to NamedElement.
/// </summary>
vector<shared_ptr<Artifact>>& Artifact::nestedArtifacts() {
    return nestedArtifacts_;
}

/// <summary>
/// ownedAttributes getter
/// The attributes or association ends defined for the Artifact. The association is
/// a specialization of the ownedMember association.
/// </summary>
vector<shared_ptr<Property>>& Artifact::ownedAttributes() {
    return ownedAttributes_;
}

/// <summary>
/// ownedOperations getter
/// The Operations defined for the Artifact. The association is a specialization of
/// the ownedMember association.
/// </summary>
vector<shared_ptr<Operation>>& Artifact::ownedOperations() {
    return ownedOperations_;
}

} // namespace uml
